package com.game.battle.service.battle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.game.battle.common.BattleEnum.EnumAttackRangeType;
import com.game.battle.common.BattleHelper;
import com.game.battle.common.BattleStep;
import com.game.battle.common.FightSceneUnit;
import com.game.battle.common.GridPosition;
import com.game.battle.common.MonsterFightUnit;
import com.game.battle.common.Player;
import com.game.battle.common.PlayerFightUnit;
import com.game.battle.common.Room;
import com.game.battle.common.Shield;
import com.game.battle.common.map.BattleMap;
import com.game.battle.common.map.PathNode;
import com.game.battle.common.math.Vector2;
import com.game.battle.common.weapon.Weapon;
import com.game.battle.config.SkillConfig;
import com.game.battle.config.WeaponConfig;
import com.game.battle.config.XMLTemplateService;
import com.game.battle.service.room.RoomService;
import com.game.battle.service.server.ServerService;
import com.game.common.Transmitter;
import com.game.common.constants.GlobalConstants;
import com.game.core.service.PublicService;
import com.game.core.service.ServiceContainer;
import com.game.dbpersistence.game.entity.ItemEntity;
import com.game.message.proto.account.AccountProtoBuf.BGAccountModifyREQ;
import com.game.message.proto.battle.BattleProtoBuf.BGSingleGameOverRES;
import com.game.message.proto.battle.BattleProtoBuf.BGTeamGameOverRES;
import com.game.message.proto.battle.BattleProtoBuf.BWCancleOperateRES;
import com.game.message.proto.battle.BattleProtoBuf.BWChangeWeaponRES;
import com.game.message.proto.battle.BattleProtoBuf.BWEnterBattleRES;
import com.game.message.proto.battle.BattleProtoBuf.BWReadyBattleRES;
import com.game.message.proto.battle.BattleProtoBuf.BWSearchPathRES;
import com.game.message.proto.battle.BattleProtoBuf.BWStartBattleRES;
import com.game.message.proto.battle.BattleProtoBuf.BWUseShieldRES;
import com.game.message.proto.battle.BattleProtoBuf.BattleStepType;
import com.game.message.proto.battle.BattleProtoBuf.FightUnitInfo;
import com.game.message.proto.battle.BattleProtoBuf.MAchieveCondition;
import com.game.message.proto.battle.BattleProtoBuf.MAchieveItem;
import com.game.message.proto.battle.BattleProtoBuf.MGameOver;
import com.game.message.proto.battle.BattleProtoBuf.MOperFightUnitInfo;
import com.game.message.proto.battle.BattleProtoBuf.MPathNode;
import com.game.message.proto.battle.BattleProtoBuf.MWeaponInfo;
import com.game.message.proto.battle.BattleProtoBuf.WBChangeWeaponREQ;
import com.game.message.proto.battle.BattleProtoBuf.WBSearchPathREQ;
import com.game.message.proto.battle.BattleProtoBuf.WBUseShieldREQ;
import com.game.message.proto.player.PlayerProtoBuf.PlayerInfo;
import com.game.message.proto.team.TeamProtoBuf.BGStartSingleBattleRES;
import com.game.message.proto.team.TeamProtoBuf.BGStartTeamBattleRES;
import com.game.message.proto.team.TeamProtoBuf.GBStartSingleBattleREQ;
import com.game.message.proto.team.TeamProtoBuf.GBStartTeamBattleREQ;
import com.game.message.proto.team.TeamProtoBuf.GBTmpDestoryRoomREQ;
import com.game.message.proto.team.TeamProtoBuf.TeamInfo;
import com.game.message.proto.team.TeamProtoBuf.TeamPlayerInfo;
import com.game.message.protocol.ProtocolsConfig;

public class BattleService extends PublicService 
{
	private static final long serialVersionUID = -8513687732800111630L;
	private static Logger logger = LoggerFactory.getLogger(BattleService.class);
	public static ConcurrentHashMap<String, BattleHelper> battleHelpers = new ConcurrentHashMap<>();
	public static ConcurrentHashMap<String, String> accountTeams = new ConcurrentHashMap<>();
//	private boolean roomOwnerMoveComplete = false;
	
	public void playerOffline(String accountId, int roomId)
	{
		RoomService roomService = ServiceContainer.getInstance().getPublicService(RoomService.class);
		Room room = roomService.getRoom(roomId);
		if(room == null)
			return;
		
		Player player = room.getPlayer(accountId);
		if(player == null)
			return;
		
//		sendPlayerStatus(accountId, roomId, true);
	}
	
	
	
	
	public void modifyAccountInfo(int roomID, String accountID, int id, Boolean alterCard, int alterPoint)
	{
		RoomService roomService = ServiceContainer.getInstance().getPublicService(RoomService.class);
		Room room = roomService.getRoom(roomID);
		if(room == null)
		{
			logger.error("BattleService room {} not found.", roomID);
			return;
		}
		Player player = room.getPlayer(accountID);
		if(player == null)
		{
			logger.error("BattleService player {} not found.", accountID);
			return;
		}
		if(alterCard)
		{
//			room.setHasSubCard(true);
		}
		player.modifyPoints(alterPoint);
		BGAccountModifyREQ.Builder builder = BGAccountModifyREQ.newBuilder();
		builder.setRoomID(roomID);
	    builder.setAccountID(accountID);
	    builder.setId(id);
	    builder.setAlterCard(alterCard);
	    ServerService server = ServiceContainer.getInstance().getPublicService(ServerService.class);
	    Transmitter.getInstance().write(server.getGameNode(), GlobalConstants.DEFAULT_CALLBACK, builder.build());
	}




	public void searchPath(WBSearchPathREQ message) {
		
		String roomId = accountTeams.get(message.getAccount());
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		BWSearchPathRES.Builder res = BWSearchPathRES.newBuilder();
		if(!message.getAccount().equals(battleMap.playerOperList.get(battleMap.playerOperIndex))){
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			res.setAccount(message.getAccount());
			res.setOperAccount(message.getAccount());
			res.setResult(ProtocolsConfig.NOT_YOUR_TURN);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
			return;
		}
		
		PlayerFightUnit playerUnit = (PlayerFightUnit)battleMap.getPlayers(BattleMap.deployStage).get(message.getAccount());
		
		playerUnit.gridPos = new GridPosition(-1, -1);
		battleMap.updateGridDatas(BattleMap.deployStage);
		
		BattleStep step = null;
		//攻击点
		GridPosition gridPosition = null;

		//1表示攻击并寻路  2表示只寻路
		int searchType = message.getSearchType();
		int result = ProtocolsConfig.SEARCH_SUCCESS;
		
		if(searchType == 1){
			//真正的攻击目标 
			res.setAttackTarget(message.getTargetId());
			FightSceneUnit targetUnit = battleMap.getEnemyById(message.getTargetId(),BattleMap.deployStage);
			
			int weaponId = playerUnit.getSelectWeaponId();
			WeaponConfig weaponConfig = XMLTemplateService.weaponConfigMap.get(weaponId);
			int skillId = weaponConfig.getMainSkillId();
			SkillConfig skillConfig = XMLTemplateService.skillConfigMap.get(skillId);
			List<PathNode> list = new ArrayList<>();
			
			if(message.hasModifyNode()){
				gridPosition = new GridPosition(message.getModifyNode().getX(), message.getModifyNode().getY());
				list = battleMap.search(message.getStart().getX(),message.getStart().getY(),
						gridPosition.getX(),gridPosition.getY());
			}else{
				//该技能是否受障碍物影响
				boolean ignoreObstacle = battleMap.checkIgnoreObstacle(skillConfig);
//				gridPosition = battleMap.autoSearchGrid(ignoreObstacle, message.getStart().getX(), message.getStart().getY(),
//						new Vector2(tarentEnemy.gridPos.getX(),targetUnit.gridPos.getY()), EnumAttackRangeType.values()[skillConfig.getAttackRangeType()], skillConfig.getMaxDist(),BattleMap.deployStage);
				list = battleMap.search(ignoreObstacle ,message.getStart().getX(),message.getStart().getY(),
						targetUnit.gridPos.getX(),targetUnit.gridPos.getY(),skillConfig.getMaxDist(), targetUnit.getRadius());
				if((list!=null)&&(list.size()>0)) {
					gridPosition= new GridPosition(list.get(list.size()-1).getX(), list.get(list.size()-1).getY());
				}
			}
			
			//说明寻路失败 出错了
			if((list==null)||(list.size()==0)) {
				// 发送玩家状态
				ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
				res.setAccount(message.getAccount());
				res.setOperAccount(message.getAccount());
				result = ProtocolsConfig.CAN_NOT_MOVE;
				res.setResult(result);
				Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
				return;
			}else{
				System.out.println("怪物最佳攻击点为:" + gridPosition.getX()+ " " + gridPosition.getY());
			}
			
			playerUnit.gridPos = gridPosition;
			
			int moveCost = (list.size()-1) * playerUnit.getMoveCap();
			int skillCost = skillConfig.getConsumePower();
			int actionCost = moveCost + skillCost;
			
			List<FightSceneUnit> reachUnits;
			
			List<FightSceneUnit> realEffectUnits;
			
			boolean isModify = false;
			if(message.hasModifyNode()){
				isModify = true;
			}
			//如果是调整
			if(isModify){
				Stack<BattleStep> stack = battleMap.playerStacks.get(message.getAccount());
				step = stack.peek();
				playerUnit.addActionPower(step.actionCost);
				if(playerUnit.getCurrentActionPower() < actionCost){
					playerUnit.costActionPower(step.actionCost);
					
					playerUnit.gridPos = new GridPosition(message.getStart().getX(),message.getStart().getY());
					battleMap.updateGridDatas(BattleMap.deployStage);
					
					// 发送玩家状态
					ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
					res.setAccount(message.getAccount());
					res.setOperAccount(message.getAccount());
					res.setResult(ProtocolsConfig.ACTION_POWER_NOT_ENOUGH);
					Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
					return;
				}
				Map<Integer, FightSceneUnit> originUnitsMap = new HashMap<Integer, FightSceneUnit>();
				originUnitsMap.put(playerUnit.getId(), playerUnit.clone());
				
				//要把前一步操作恢复的数据传给客户端
				List<FightSceneUnit> effectUnits = step.effectUnits;
				if(effectUnits != null && effectUnits.size() > 0){
					for(FightSceneUnit unit : effectUnits){
						//上次影响的先恢复回去
						FightSceneUnit realUnit = battleMap.getEnemyObstacleById(unit.getId(),BattleMap.deployStage);
						if(realUnit != null){
							realUnit.resetByClone(step.effectOrigiFightSceneUnits,unit);
							res.addLastEffectedUnits(realUnit.toProto());
						}
					}
				}
				
				//叠加次数的天赋
				List<Integer> triggeredAddTalents = battleMap.checkDeployTriggerAddTalents(playerUnit,message.getAccount(),isModify);
				//连击的天赋 中间可以夹杂行走 上盾其他逻辑
				List<Integer> triggeredSeriAttackTalents = battleMap.checkDeployTriggerSeriAttackTalents(playerUnit,message.getAccount());
				List<Integer> triggeredAttackTarTalents = battleMap.checkTriggerAttackTarTalents(playerUnit,targetUnit);
				List<Integer> triggeredTalents = new ArrayList<>();
				
				triggeredTalents.addAll(triggeredAddTalents);
				triggeredTalents.addAll(triggeredSeriAttackTalents);
				triggeredTalents.addAll(triggeredAttackTarTalents);
				
				res.addAllTriggeredTalents(triggeredTalents);
				step.stepType = BattleStepType.Attact;
				
				
				//要先恢复回去再重新寻路 不然会有已经被打死的怪寻不到的问题
				reachUnits = battleMap.useSkill(skillConfig,true, battleMap.getTargetGridPos(gridPosition.getX(), gridPosition.getY()),
						battleMap.getTargetGridPos(targetUnit.gridPos.getX(),targetUnit.gridPos.getY()), targetUnit,
						EnumAttackRangeType.values()[skillConfig.getAttackRangeType()],BattleMap.deployStage);
				
				realEffectUnits = battleMap.getEffectUnitsByDeploySkill(step,playerUnit,skillConfig,reachUnits,originUnitsMap,triggeredTalents);
				
				for(FightSceneUnit unit : realEffectUnits){
					if(unit.getId() != playerUnit.getId()){
						unit.takeEffect();
					}
				}
				for(FightSceneUnit unit : realEffectUnits){
					res.addEffectUnits(unit.toProto());
				}
				playerUnit.gridPos = gridPosition;
				step.attacker = playerUnit.clone();
				step.effectOrigiFightSceneUnits = originUnitsMap;
				step.actionCost = actionCost;
				step.refreshUnits(realEffectUnits);
				step.refreshPathNodes(list);
				playerUnit.costActionPower(actionCost);
			}else {
				//如果是直接攻击
				Stack<BattleStep> stack = battleMap.playerStacks.get(message.getAccount());
				BattleStep laStep = null;
				if(stack != null && stack.size() > 0){
					laStep = stack.peek();
				}
				boolean needAddStep = false;
				boolean recoverActionPowerFlag = false;
				
				if(laStep != null && laStep.searchType == 2){
					step = laStep;
					playerUnit.addActionPower(step.actionCost);
					recoverActionPowerFlag = true;
				}else {
					step = new BattleStep();
					needAddStep = true;
				}
				//新需求 最后一步如果行动力不够那么直移动不攻击
				//需要移动加攻击的情况
				if(list.size() > 1){
					if(playerUnit.getCurrentActionPower() < playerUnit.getMoveCap()){
						if(recoverActionPowerFlag){
							playerUnit.costActionPower(step.actionCost);
						}
						playerUnit.gridPos = new GridPosition(message.getStart().getX(),message.getStart().getY());
						battleMap.updateGridDatas(BattleMap.deployStage);
						
						// 发送玩家状态
						ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
						res.setAccount(message.getAccount());
						res.setOperAccount(message.getAccount());
						res.setResult(ProtocolsConfig.ACTION_POWER_NOT_ENOUGH);
						Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
						return;
					}else if(playerUnit.getCurrentActionPower() >=  playerUnit.getMoveCap() && playerUnit.getCurrentActionPower() < actionCost){
						int realMoveCost = 0;
						List<PathNode> moveList = new ArrayList<>();
						//这里包含起始点 所以需要注意加一步减一步的操作
						int canMoveCount = Math.min((playerUnit.getCurrentActionPower()+playerUnit.getMoveCap()) / playerUnit.getMoveCap(), list.size());
						for(int i = 0; i < canMoveCount; i++){
							moveList.add(list.get(i));
						}
						gridPosition = new GridPosition(moveList.get(canMoveCount-1).getX(), moveList.get(canMoveCount-1).getY());
						playerUnit.gridPos = gridPosition;
						list = moveList;
						step.stepType = BattleStepType.Search;
						realMoveCost = (canMoveCount-1) * playerUnit.getMoveCap();
						step.actionCost = realMoveCost;
						searchType = 2;
						
						step.attacker = playerUnit.clone();
						
						step.startPos = new GridPosition(message.getStart().getX(), message.getStart().getY());
						step.endPos = gridPosition;
						step.account = message.getAccount();
						step.searchPathNodes = list;
						step.actionCost = realMoveCost;
						step.searchType = searchType;
						step.weaponCfgId = playerUnit.getSelectWeaponId();
						playerUnit.costActionPower(realMoveCost);
						result = ProtocolsConfig.ACTION_POWER_NOT_ENOUGH;
						if(needAddStep){
							battleMap.addStep(message.getAccount(),step);
						}
					}
				}else{//只需要攻击的情况
					if(playerUnit.getCurrentActionPower() < skillCost){
						if(recoverActionPowerFlag){
							playerUnit.costActionPower(step.actionCost);
						}
						playerUnit.gridPos = new GridPosition(message.getStart().getX(),message.getStart().getY());
						battleMap.updateGridDatas(BattleMap.deployStage);
						
						// 发送玩家状态
						ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
						res.setAccount(message.getAccount());
						res.setOperAccount(message.getAccount());
						res.setResult(ProtocolsConfig.ACTION_POWER_NOT_ENOUGH);
						Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
						return;
					}
				}
				
				
				if(playerUnit.getCurrentActionPower() >= skillCost){
					Map<Integer, FightSceneUnit> originUnitsMap = new HashMap<Integer, FightSceneUnit>();
					originUnitsMap.put(playerUnit.getId(), playerUnit.clone());
					
					//叠加次数的天赋
					List<Integer> triggeredAddTalents = battleMap.checkDeployTriggerAddTalents(playerUnit,message.getAccount(),isModify);
					//连击的天赋 中间可以夹杂行走 上盾其他逻辑
					List<Integer> triggeredSeriAttackTalents = battleMap.checkDeployTriggerSeriAttackTalents(playerUnit,message.getAccount());
					List<Integer> triggeredAttackTarTalents = battleMap.checkTriggerAttackTarTalents(playerUnit,targetUnit);
					List<Integer> triggeredTalents = new ArrayList<>();
					
					triggeredTalents.addAll(triggeredAddTalents);
					triggeredTalents.addAll(triggeredSeriAttackTalents);
					triggeredTalents.addAll(triggeredAttackTarTalents);
					res.addAllTriggeredTalents(triggeredTalents);
					
					reachUnits = battleMap.useSkill(skillConfig,true, battleMap.getTargetGridPos(gridPosition.getX(), gridPosition.getY()),
							battleMap.getTargetGridPos(targetUnit.gridPos.getX(),targetUnit.gridPos.getY()), targetUnit,
							EnumAttackRangeType.values()[skillConfig.getAttackRangeType()],BattleMap.deployStage);
					realEffectUnits = battleMap.getEffectUnitsByDeploySkill(step,playerUnit,skillConfig,reachUnits,originUnitsMap,triggeredTalents);
					
					step.stepType = BattleStepType.Attact;
					step.stepX = targetUnit.gridPos.getX();
					step.stepY = targetUnit.gridPos.getY();
					step.targetId = targetUnit.getId();
					step.skillId = skillId;
					step.attacker = playerUnit.clone();
					step.effectOrigiFightSceneUnits = originUnitsMap;
					for(FightSceneUnit unit : realEffectUnits){
						if(unit.getId() != playerUnit.getId()){
							unit.takeEffect();
						}
						step.effectUnits.add(unit.clone());
					}
					step.startPos = new GridPosition(message.getStart().getX(), message.getStart().getY());
					step.endPos = gridPosition;
					step.account = message.getAccount();
					step.searchPathNodes = list;
					step.weaponCfgId = weaponId;
					step.actionCost = actionCost;
					step.searchType = searchType;
					
					if(needAddStep){
						battleMap.addStep(message.getAccount(),step);
					}
					playerUnit.costActionPower(actionCost);
					for(FightSceneUnit unit : realEffectUnits){
						
						res.addEffectUnits(unit.toProto());
					}
				}
				
			}
			
			for(PathNode pathNode : list){
				MPathNode.Builder mPathNode = MPathNode.newBuilder();
				mPathNode.setX(pathNode.getX());
				mPathNode.setY(pathNode.getY());
				res.addPathNodes(mPathNode);
			}
			
		}else {//只寻路的情况
			gridPosition = new GridPosition(message.getDesNode().getX(), message.getDesNode().getY());
			
			List<PathNode> list = battleMap.search(message.getStart().getX(),message.getStart().getY(),
													gridPosition.getX(),gridPosition.getY());
			//说明寻路失败 出错了
			if(list == null){
				// 发送玩家状态
				ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
				res.setAccount(message.getAccount());
				res.setOperAccount(message.getAccount());
				res.setResult(ProtocolsConfig.ACTION_POWER_NOT_ENOUGH);
				Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
				return;
			}
			
			int actionCost = (list.size()-1) * playerUnit.getMoveCap();
			
			boolean needAddStep = false;
			boolean recoverActionPowerFlag = false;
			Stack<BattleStep> stack = battleMap.playerStacks.get(message.getAccount());
			if(stack == null || stack.size() == 0){
				step = new BattleStep();
				needAddStep = true;
			}else {
				BattleStep lastStep = stack.peek();
				if(lastStep.stepType != BattleStepType.Search){
					step = new BattleStep();
					needAddStep = true;
				}else{
					step = lastStep;
					playerUnit.addActionPower(step.actionCost);
					recoverActionPowerFlag = true;
				}
			}
			step.stepType = BattleStepType.Search;
			int realMoveCost = actionCost;
			if(playerUnit.getCurrentActionPower() < actionCost){
				if(playerUnit.getCurrentActionPower() < playerUnit.getMoveCap()){
					if(recoverActionPowerFlag){
						playerUnit.costActionPower(step.actionCost);
					}
					ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
					res.setAccount(message.getAccount());
					res.setOperAccount(message.getAccount());
					res.setResult(ProtocolsConfig.ACTION_POWER_NOT_ENOUGH);
					Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
					return;
				}
				List<PathNode> moveList = new ArrayList<>();
				int canMoveCount = (playerUnit.getCurrentActionPower()+playerUnit.getMoveCap()) / playerUnit.getMoveCap();
				for(int i = 0; i < canMoveCount; i++){
					moveList.add(list.get(i));
				}
				realMoveCost = (canMoveCount-1) * playerUnit.getMoveCap();
				gridPosition = new GridPosition(moveList.get(canMoveCount-1).getX(), moveList.get(canMoveCount-1).getY());
				list = moveList;
				result = ProtocolsConfig.ACTION_POWER_NOT_ENOUGH;
			}
			playerUnit.gridPos = gridPosition;
			for(PathNode pathNode : list){
				MPathNode.Builder mPathNode = MPathNode.newBuilder();
				mPathNode.setX(pathNode.getX());
				mPathNode.setY(pathNode.getY());
				res.addPathNodes(mPathNode);
			}
			step.attacker = playerUnit.clone();
			
			step.startPos = new GridPosition(message.getStart().getX(), message.getStart().getY());
			step.endPos = gridPosition;
			step.account = message.getAccount();
			step.searchPathNodes = list;
			step.actionCost = realMoveCost;
			step.searchType = searchType;
			
			step.weaponCfgId = playerUnit.getSelectWeaponId();
			playerUnit.costActionPower(realMoveCost);
			if(needAddStep){
				battleMap.addStep(message.getAccount(),step);
			}
		}
		//把所有玩家信息推送过去
		for(Entry<String, PlayerFightUnit> entry : battleMap.getPlayers(BattleMap.deployStage).entrySet()){
			FightUnitInfo.Builder uintInfo = FightUnitInfo.newBuilder();
			uintInfo.setAccount(entry.getKey());
			uintInfo.setId(entry.getValue().getId());
			if(entry.getKey().equals(battleMap.roomOwner)){
				uintInfo.setRoleType(1);
			}else {
				uintInfo.setRoleType(0);
			}
			MPathNode.Builder posNode = MPathNode.newBuilder();
			posNode.setX(entry.getValue().gridPos.getX());
			posNode.setY(entry.getValue().gridPos.getY());
			uintInfo.setPos(posNode);
			uintInfo.setCurrentHp(entry.getValue().getCurrentHp());
			uintInfo.setTotalHp(entry.getValue().getTotalHp());
			uintInfo.setTotalActionPower(entry.getValue().getTotalActionPower());
			uintInfo.setCurrentActionPower(entry.getValue().getCurrentActionPower());
			
			for(Weapon weapon : entry.getValue().getWeapons()){
				MWeaponInfo.Builder weaponInfo = MWeaponInfo.newBuilder();
				weaponInfo.setWeaponId(weapon.getCfgId());
				uintInfo.addWeaponInfo(weaponInfo);
			}
			uintInfo.setSelectedWeapon(entry.getValue().getSelectWeaponId());
			MWeaponInfo.Builder weaponInfo = MWeaponInfo.newBuilder();
			weaponInfo.setWeaponId(entry.getValue().getSelectWeaponId());
			res.addFightUnits(uintInfo);
		}
		
		battleMap.updateGridDatas(BattleMap.deployStage);
		res.setResult(result);
		res.setOperAccount(message.getAccount());
		res.setStep(step.stepNumber);
		res.setSearchType(searchType);
		for(String acc : battleMap.playerOperList){
			res.setAccount(acc);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
	}

	/**
	 * 进入战斗
	 * @param account
	 */
	public void enterBattle(String account) {
		
		String roomId = accountTeams.get(account);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		
		BWEnterBattleRES.Builder resBuilder = BWEnterBattleRES.newBuilder();
		for(String acc : battleMap.playerOperList){
			PlayerFightUnit playerFightSceneUnit = battleMap.getPlayers(BattleMap.deployStage).get(acc);
			FightUnitInfo.Builder uintInfo = FightUnitInfo.newBuilder();
			uintInfo.setAccount(acc);
			uintInfo.setId(playerFightSceneUnit.getId());
			if(acc.equals(battleMap.roomOwner)){
				uintInfo.setRoleType(1);
			}else {
				uintInfo.setRoleType(0);
			}
			MPathNode.Builder posNode = MPathNode.newBuilder();
			posNode.setX(playerFightSceneUnit.gridPos.getX());
			posNode.setY(playerFightSceneUnit.gridPos.getY());
			uintInfo.setCurrentHp(playerFightSceneUnit.getCurrentHp());
			uintInfo.setTotalHp(playerFightSceneUnit.getTotalHp());
			uintInfo.setTotalActionPower(playerFightSceneUnit.getTotalActionPower());
			uintInfo.setCurrentActionPower(playerFightSceneUnit.getCurrentActionPower());
			uintInfo.setPos(posNode);
			for(Weapon weapon : playerFightSceneUnit.getWeapons()){
				MWeaponInfo.Builder weaponInfo = MWeaponInfo.newBuilder();
				weaponInfo.setWeaponId(weapon.getCfgId());
				WeaponConfig weaponConfig = XMLTemplateService.weaponConfigMap.get(weapon.getCfgId());
				SkillConfig skillConfig = XMLTemplateService.skillConfigMap.get(weaponConfig.getMainSkillId());
				int weaponDamage = (int)(playerFightSceneUnit.getAttack()*skillConfig.getConvertNum() + skillConfig.getAddDamage());
				weaponInfo.setWeaponDamage(weaponDamage);
				uintInfo.addWeaponInfo(weaponInfo);
			}
			uintInfo.setSelectedWeapon(playerFightSceneUnit.getSelectWeaponId());
			uintInfo.setFashionInfo(playerFightSceneUnit.getFashion().toProto());
			uintInfo.setSex(playerFightSceneUnit.getSex());
			uintInfo.setName(playerFightSceneUnit.getName());
			resBuilder.addFightUnits(uintInfo);
		}
		List<MonsterFightUnit> enemys = battleMap.getMonsters(BattleMap.deployStage);
		if(enemys != null){
			for(FightSceneUnit enemy : enemys){
				resBuilder.addEnemyObstacles(enemy.toProto());
			}
		}
		
		List<FightSceneUnit> obstacles = battleMap.getObstacles(BattleMap.deployStage);
		if(obstacles != null){
			for(FightSceneUnit obstacle : obstacles){
				resBuilder.addEnemyObstacles(obstacle.toProto());
			}
		}
		
		MOperFightUnitInfo.Builder operFightUnitbuBuilder = MOperFightUnitInfo.newBuilder();
		operFightUnitbuBuilder.setAccount(battleMap.playerOperList.get(battleMap.playerOperIndex));
		resBuilder.setOperFightUnitInfo(operFightUnitbuBuilder);
		resBuilder.setMapIndex(battleMap.mapLevelItemConfig.getStap1GridIndex());
		
		for(String acc : battleMap.playerOperList){
			resBuilder.setAccount(acc);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, resBuilder.build());
		}
		
	}

	/**
	 * 开始战斗
	 * @param account
	 */
	public void startBattle(String account) {
		String roomId = accountTeams.get(account);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		BWStartBattleRES.Builder res = BWStartBattleRES.newBuilder();
		
		for(String player : battleMap.playerOperList){
			Stack<BattleStep> stack = battleMap.playerStacks.get(player);
			if(stack != null && stack.size() > 0){
				List<BattleStep> steps = new ArrayList<>();
				int size = stack.size();
				for (int i = 0; i < size; i++) {
					BattleStep step = stack.pop();
					steps.add(step);
				}
				int attackCount = 0;
				for (int i = size-1; i >= 0; i--) {
					BattleStep step = steps.get(i);
					if(step.stepType == BattleStepType.Attact){
						attackCount++;
					}
					battleMap.takeRealEffect(step,attackCount);
					res.addBattleSteps(step.toProto(player));
				}
			}
		}
		
		//先是人打机器人 后是机器人打人
		List<BattleStep> mosterSteps = battleMap.monsterAction();
		for(BattleStep step : mosterSteps){
			res.addBattleSteps(step.mosterStepToProto(step.attacker.getId()));
		}
		
		battleMap.refreshBuff();
		for(PlayerFightUnit pUnit : battleMap.getAlivePlayers(BattleMap.realStage)){
			res.addFightUnits(pUnit.toProto());
		}
		List<MonsterFightUnit> monsters = battleMap.getAliveMonsters(BattleMap.realStage);
		for(FightSceneUnit monster : monsters){
			res.addFightUnits(monster.toProto());
		}
	
		int isGameOver = battleMap.checkMapChangeStageOrGameOver(res);

		// 在触发点调用完后进行一次
		battleMap.achievementService.settleAchievement();
		List<MAchieveCondition.Builder> achieveConditionBuilderList = battleMap.achievementService.getAchieveConditionBuilderList();
		for (MAchieveCondition.Builder achieveConditionBuilder : achieveConditionBuilderList) {
			res.addAchieveCondition(achieveConditionBuilder);
		}
		
		if(isGameOver > 0){//游戏成功结束
			MGameOver.Builder gameOverBuidlder = MGameOver.newBuilder();
			gameOverBuidlder.setResult(1);
			res.setGameOverInfo(gameOverBuidlder);
			destoryRoom(roomId);
			String[] params = roomId.split("_");
			if ("team".equals(params[0])) {
				BGTeamGameOverRES.Builder bgGameOverRes = BGTeamGameOverRES.newBuilder();
				bgGameOverRes.setMissionId(Integer.parseInt(params[1]));
				bgGameOverRes.setTeamId(Long.parseLong(params[2]));
				//TODO 临时使用战斗结果做下一关卡是否开启的标志
				bgGameOverRes.setAchievement(Integer.toString(res.getGameOverInfo().getResult()));
				//TODO 游戏成功结束，给玩家怪物掉落奖励
				for (Entry<Integer, ItemEntity> items : battleMap.monstersDropItems.entrySet()) {
					ItemEntity dropItem = items.getValue();
					if (dropItem != null) {
						bgGameOverRes.addMonstersDropItems(dropItem.toProto());
					}
				}
				//TODO 游戏成功结束，给玩家关卡掉落奖励
				for (Entry<Integer, ItemEntity> items : battleMap.gamecopyDropItems.entrySet()) {
					ItemEntity dropItem = items.getValue();
					if (dropItem != null) {
						bgGameOverRes.addGamecopyDropItems(dropItem.toProto());
					}
				}
				//TODO 游戏成功结束，给玩家关卡成就奖励
				for (String acc : battleMap.playerAchievementItems.keySet()) {	
					MAchieveItem.Builder achieveItem = MAchieveItem.newBuilder();
					achieveItem.setAccount(acc);
					List<ItemEntity> achieveItemsList = battleMap.playerAchievementItems.get(acc);	
					for (ItemEntity dropItem : achieveItemsList) {
						if (dropItem != null) {
							achieveItem.addAchieveRewardItems(dropItem.toProto());
						}
					}
					List<String> achievementList = battleMap.achievementService.playerCompleteAchievementListMap.get(acc);
					achieveItem.addAllAchievementCondition(achievementList);
					bgGameOverRes.addAchieveItems(achieveItem);	
				}
				
				ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
				Transmitter.getInstance().write(serverService.getGameNode(), GlobalConstants.DEFAULT_CALLBACK, bgGameOverRes.build());
			} else {
				BGSingleGameOverRES.Builder bgSingleGameOverRes = BGSingleGameOverRES.newBuilder();
				bgSingleGameOverRes.setMissionId(Integer.parseInt(params[1]));
				bgSingleGameOverRes.setAccount(params[2]);
				//TODO 临时使用战斗结果做下一关卡是否开启的标志
				bgSingleGameOverRes.setAchievement(Integer.toString(res.getGameOverInfo().getResult()));
				//TODO 游戏成功结束，给玩家怪物掉落奖励
				for (Entry<Integer, ItemEntity> items : battleMap.monstersDropItems.entrySet()) {
					ItemEntity dropItem = items.getValue();
					if (dropItem != null) {
						bgSingleGameOverRes.addMonstersDropItems(dropItem.toProto());
					}
				}
				//TODO 游戏成功结束，给玩家关卡掉落奖励
				for (Entry<Integer, ItemEntity> items : battleMap.gamecopyDropItems.entrySet()) {
					ItemEntity dropItem = items.getValue();
					if (dropItem != null) {
						bgSingleGameOverRes.addGamecopyDropItems(dropItem.toProto());
					}
				}
				//TODO 游戏成功结束，给玩家关卡成就奖励
				List<ItemEntity> achieveItemsList = battleMap.playerAchievementItems.get(params[2]);
				for (ItemEntity dropItem : achieveItemsList) {
					if (dropItem != null) {
						bgSingleGameOverRes.addAchieveRewardItems(dropItem.toProto());
					}
				}
				List<String> playerCompleteAchievementList = battleMap.achievementService.playerCompleteAchievementListMap.get(params[2]);	
				bgSingleGameOverRes.addAllAchievementCondition(playerCompleteAchievementList);
				ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
				Transmitter.getInstance().write(serverService.getGameNode(), GlobalConstants.DEFAULT_CALLBACK, bgSingleGameOverRes.build());
			}
		}
		else if(isGameOver < 0){//游戏失败结束
			MGameOver.Builder gameOverBuidlder = MGameOver.newBuilder();
			gameOverBuidlder.setResult(2);
			res.setGameOverInfo(gameOverBuidlder);
			destoryRoom(roomId);
		}
		else {//游戏没有结束
			battleMap.reset();
			battleMap.updateGridDatas(BattleMap.realStage);
			battleMap.addBattleRound();
			battleMap.updateDeployUnitsByRealSceneUnits();
			battleMap.updateOperIndex(BattleMap.realStage);
		}
		
		MOperFightUnitInfo.Builder operFightUnitInfoBuilder = MOperFightUnitInfo.newBuilder();
		operFightUnitInfoBuilder.setAccount(battleMap.playerOperList.get(battleMap.playerOperIndex));
		res.setOperFightUnitInfo(operFightUnitInfoBuilder);
		
		
		for(String acc : battleMap.playerOperList){
			res.setAccount(acc);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
	}


	/**
	 * 
	 * @param roomId
	 */
	private void destoryRoom(String roomId) {
		BattleHelper battleHelper = battleHelpers.get(roomId);
		if (battleHelper != null) {
			BattleMap battleMap = battleHelper.battleMap;
			
			if (battleMap != null) {
				for(String player : battleMap.playerOperList){
					accountTeams.remove(player);
				}
			}
			battleHelpers.remove(roomId);
		}
	}




	/**
	 * 玩家部署完点击准备
	 * @param account
	 */
	public void readyBattle(String account) {
		String roomId = accountTeams.get(account);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		
		//先检测是否是最后一个人
		if(battleMap.checkLastOperatpr(account)){
			startBattle(account);
			return;
		}
		battleMap.updateOperIndex(BattleMap.deployStage);
//		//找到下一个还活着的
//		if(battleMap.playerOperIndex == battleMap.playerOperList.size()-1){
//			battleMap.playerOperIndex = 0;//最后一个人点了准备 下一个该操作的人变为第一个人
//		}else {
//			battleMap.playerOperIndex += 1;
//		}
		
		BWReadyBattleRES.Builder res = BWReadyBattleRES.newBuilder();
		
		String operAccount = battleMap.playerOperList.get(battleMap.playerOperIndex);
		MOperFightUnitInfo.Builder operFightUnitInfoBuilder = MOperFightUnitInfo.newBuilder();
		operFightUnitInfoBuilder.setAccount(operAccount);
		
		
		MWeaponInfo.Builder weaponInfoBuilder = MWeaponInfo.newBuilder();
		weaponInfoBuilder.setWeaponId(1);
		
		res.setOperAccount(account);
		res.setOperFightUnitInfo(operFightUnitInfoBuilder);
		
		for(String acc : battleMap.playerOperList){
			res.setAccount(acc);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
		
//		// 发送玩家状态
//		ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
//		Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
	}



	/**
	 * 撤回操作
	 * @param account
	 */
	public void cancleOperate(String account) {
		String roomId = accountTeams.get(account);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		PlayerFightUnit playerUnit = (PlayerFightUnit)battleMap.getPlayers(BattleMap.deployStage).get(account);
		
		BWCancleOperateRES.Builder res = BWCancleOperateRES.newBuilder();
		Stack<BattleStep> stack = battleMap.playerStacks.get(account);
		if(stack.isEmpty()){
			res.setOperAccount(account);
			res.setAccount(account);
			res.setResult(0);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
		}else {
			
			PlayerFightUnit realPlayerUnit = (PlayerFightUnit)battleMap.getPlayers(BattleMap.realStage).get(account);
			//把武器置为上一次的
			if(stack.size() <= 0){
				playerUnit.setSelectWeaponId(playerUnit.getInitWeaponId());
				realPlayerUnit.setSelectWeaponId(playerUnit.getInitWeaponId());
			}else {
				BattleStep preStep = stack.peek();
				int weaponId = preStep.weaponCfgId;
				playerUnit.setSelectWeaponId(weaponId);
				realPlayerUnit.setSelectWeaponId(weaponId);
			}
			
			res.setOperAccount(account);
			res.setResult(1);
			BattleStep step = stack.pop();
			res.setStep(step.stepNumber);
			if(step.stepType == BattleStepType.UseShield){
//				List<FightSceneUnit> effectUnits = step.effectUnits;
//				if(effectUnits != null && effectUnits.size() > 0){
//					for(int i =0;i<effectUnits.size();i++){
//						PlayerFightUnit cloneUnit = (PlayerFightUnit)effectUnits.get(i);
//						PlayerFightUnit playerFightSceneUnit = null;
//						for(String acc : battleMap.playerOperList){
//							playerFightSceneUnit = battleMap.getPlayers(BattleMap.deployStage).get(acc);
//							if(playerFightSceneUnit.getId() == cloneUnit.getId()){
//								playerFightSceneUnit.removeShield();
//							}
//						}
//						if(playerFightSceneUnit != null){
//							res.addLastEffectedUnits(playerFightSceneUnit.toProto());
//						}
//					}
//				}
				FightSceneUnit originOperUnit = step.effectOrigiFightSceneUnits.get(playerUnit.getId());
				if(originOperUnit != null){
					playerUnit.removeShield();
					playerUnit.resetByClone(step.effectOrigiFightSceneUnits, originOperUnit);
					res.addLastEffectedUnits(playerUnit.toProto());
				}
			}else {
				List<FightSceneUnit> effectUnits = step.effectUnits;
				if(effectUnits != null && effectUnits.size() > 0){
					for(FightSceneUnit unit : effectUnits){
						//上次影响的先恢复回去
						FightSceneUnit realUnit = battleMap.getEnemyObstacleById(unit.getId(),BattleMap.deployStage);
						if(realUnit != null){
							realUnit.resetByClone(step.effectOrigiFightSceneUnits,unit);
							res.addLastEffectedUnits(realUnit.toProto());
						}
//						FightSceneUnit pUnit = battleMap.getPlayers(BattleMap.deployStage).get(unit.getId());
//						if(pUnit != null){
//							pUnit.resetByClone(step.effectOrigiFightSceneUnits,unit);
//							res.addLastEffectedUnits(pUnit.toProto());
//						}
					}
				}
				FightSceneUnit originOperUnit = step.effectOrigiFightSceneUnits.get(playerUnit.getId());
				if(originOperUnit != null){
					playerUnit.resetByClone(step.effectOrigiFightSceneUnits, originOperUnit);
					res.addLastEffectedUnits(playerUnit.toProto());
//					playerUnit.costActionPower(step.actionCost);
				}
				playerUnit.gridPos = new GridPosition(step.startPos.getX(), step.startPos.getY());
				MPathNode.Builder pos = MPathNode.newBuilder();
				pos.setX(playerUnit.gridPos.getX());
				pos.setY(playerUnit.gridPos.getY());
				res.setPos(pos);
				
				battleMap.updateGridDatas(BattleMap.deployStage);
			}
			
			playerUnit.addActionPower(step.actionCost);
			
			
			for(String acc : battleMap.playerOperList){
				PlayerFightUnit playerFightSceneUnit = battleMap.getPlayers(BattleMap.deployStage).get(acc);
				FightUnitInfo.Builder uintInfo = FightUnitInfo.newBuilder();
				uintInfo.setAccount(acc);
				uintInfo.setId(playerFightSceneUnit.getId());
				if(acc.equals(battleMap.roomOwner)){
					uintInfo.setRoleType(1);
				}else {
					uintInfo.setRoleType(0);
				}
				MPathNode.Builder posNode = MPathNode.newBuilder();
				posNode.setX(playerFightSceneUnit.gridPos.getX());
				posNode.setY(playerFightSceneUnit.gridPos.getY());
				uintInfo.setCurrentHp(playerFightSceneUnit.getCurrentHp());
				uintInfo.setTotalHp(playerFightSceneUnit.getTotalHp());
				uintInfo.setTotalActionPower(playerFightSceneUnit.getTotalActionPower());
				uintInfo.setCurrentActionPower(playerFightSceneUnit.getCurrentActionPower());
				uintInfo.setPos(posNode);
				
				for(Weapon weapon : playerFightSceneUnit.getWeapons()){
					MWeaponInfo.Builder weaponInfo = MWeaponInfo.newBuilder();
					weaponInfo.setWeaponId(weapon.getCfgId());
					uintInfo.addWeaponInfo(weaponInfo);
				}
				uintInfo.setSelectedWeapon(playerFightSceneUnit.getSelectWeaponId());
				res.addFightUnits(uintInfo);
			}
			
			for(String acc : battleMap.playerOperList){
				res.setAccount(acc);
				// 发送玩家状态
				ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
				Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
			}
		}
	}
	
	/**
	 * 检查玩家的部署情况
	 */
	public void checkDeployTime(){
//		System.out.println("当前的房间数:"+battleHelpers.size());
//		for(BattleHelper battleHelper : battleHelpers.values()){
//			BattleMap battleMap = battleHelper.battleMap;
//			
//		}
	}



	/**
	 * 换武器
	 * @param message
	 * @param callback
	 */
	public void changeWeapon(WBChangeWeaponREQ message, int callback) {
		String account = message.getAccount();
		String roomId = accountTeams.get(account);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		
		int weaponCfgId = message.getWeaponCfgId();
		PlayerFightUnit playerUnit = (PlayerFightUnit)battleMap.getPlayers(BattleMap.deployStage).get(account);
		PlayerFightUnit realPlayerUnit = (PlayerFightUnit)battleMap.getPlayers(BattleMap.realStage).get(account);
		playerUnit.setSelectWeaponId(weaponCfgId);
		realPlayerUnit.setSelectWeaponId(weaponCfgId);
		
		
		BWChangeWeaponRES.Builder res = BWChangeWeaponRES.newBuilder();
		res.setOperAccount(account);
		
		MWeaponInfo.Builder weaponInfo = MWeaponInfo.newBuilder();
		weaponInfo.setWeaponId(weaponCfgId);
		res.setWeaponInfo(weaponInfo);
		
		for(String acc : battleMap.playerOperList){
			res.setAccount(acc);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
	}



	/**
	 * 使用护盾
	 * @param message
	 * @param callback
	 */
	public void useShield(WBUseShieldREQ message, int callback) {
		String account = message.getAccount();
		String roomId = accountTeams.get(account);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		BattleMap battleMap = battleHelper.battleMap;
		PlayerFightUnit playerUnit = (PlayerFightUnit)battleMap.getPlayers(BattleMap.deployStage).get(account);
		
		BWUseShieldRES.Builder res = BWUseShieldRES.newBuilder();
		res.setOperAccount(account);
		
		if(!message.getAccount().equals(battleMap.playerOperList.get(battleMap.playerOperIndex))){
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			res.setAccount(message.getAccount());
			res.setOperAccount(message.getAccount());
			res.setResult(ProtocolsConfig.NOT_YOUR_TURN);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
			return;
		}
		WeaponConfig weaponConfig = XMLTemplateService.weaponConfigMap.get(playerUnit.getSelectWeaponId());
		//当前带的不是盾的武器
		if(weaponConfig.getWeaponType() != 4){
		//if(playerUnit.getSelectWeapon().getWeaponType() != 4){
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			res.setAccount(message.getAccount());
			res.setOperAccount(message.getAccount());
			res.setResult(ProtocolsConfig.CAN_NOT_USE_SHIELD);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
			return;
		}
		
		SkillConfig skillConfig = XMLTemplateService.skillConfigMap.get(weaponConfig.getMainSkillId());
		int actionCost = skillConfig.getConsumePower();
		if(playerUnit.getCurrentActionPower() < actionCost){
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			res.setAccount(message.getAccount());
			res.setOperAccount(message.getAccount());
			res.setResult(ProtocolsConfig.POWER_NOT_ENOUGH);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
			return;
		}
		
		Map<Integer, FightSceneUnit> originUnitsMap = new HashMap<Integer, FightSceneUnit>();
		originUnitsMap.put(playerUnit.getId(), playerUnit.clone());
		
		BattleStep step = new BattleStep();
		
		step.effectOrigiFightSceneUnits = originUnitsMap;
		step.stepType = BattleStepType.UseShield;
		step.targetId = playerUnit.getId();
		step.skillId = weaponConfig.getMainSkillId();
		step.attacker = playerUnit.clone();
		Shield shield = new Shield();
		int power = (int)(playerUnit.getAttack()*skillConfig.getConvertNum()+skillConfig.getAddShield());
		shield.setTotalPower(power);
		shield.setCurrentPower(power);
		playerUnit.addShield(shield);
		
		List<FightSceneUnit> realUnits = new ArrayList<>();
		realUnits.add(playerUnit);
		battleMap.checkAddBuff(playerUnit, skillConfig, realUnits);
		
		step.effectUnits.add(playerUnit.clone());
		
		step.account = message.getAccount();
		step.weaponCfgId = playerUnit.getSelectWeaponId();
		step.actionCost = actionCost;
		
		playerUnit.costActionPower(actionCost);
		
		battleMap.addStep(message.getAccount(),step);
		
		for(String acc : battleMap.playerOperList){
			PlayerFightUnit playerFightSceneUnit = battleMap.getPlayers(BattleMap.deployStage).get(acc);
			FightUnitInfo.Builder uintInfo = FightUnitInfo.newBuilder();
			uintInfo.setAccount(acc);
			uintInfo.setId(playerFightSceneUnit.getId());
			if(acc.equals(battleMap.roomOwner)){
				uintInfo.setRoleType(1);
			}else {
				uintInfo.setRoleType(0);
			}
			MPathNode.Builder posNode = MPathNode.newBuilder();
			posNode.setX(playerFightSceneUnit.gridPos.getX());
			posNode.setY(playerFightSceneUnit.gridPos.getY());
			uintInfo.setCurrentHp(playerFightSceneUnit.getCurrentHp());
			uintInfo.setTotalHp(playerFightSceneUnit.getTotalHp());
			uintInfo.setTotalActionPower(playerFightSceneUnit.getTotalActionPower());
			uintInfo.setCurrentActionPower(playerFightSceneUnit.getCurrentActionPower());
			uintInfo.setPos(posNode);
			
			for(Weapon weapon : playerFightSceneUnit.getWeapons()){
				MWeaponInfo.Builder weaponInfo = MWeaponInfo.newBuilder();
				weaponInfo.setWeaponId(weapon.getCfgId());
				uintInfo.addWeaponInfo(weaponInfo);
			}
			uintInfo.setSelectedWeapon(playerFightSceneUnit.getSelectWeaponId());
			res.addFightUnits(uintInfo);
		}
		
		for(FightSceneUnit unit : realUnits){
			res.addEffectUnits(unit.toProto());
		}
		res.setStep(step.stepNumber);
		res.setShieldInfo(shield.toProto());
		res.setResult(ProtocolsConfig.USE_SHIELD_SUCCESS);
		for(String acc : battleMap.playerOperList){
			res.setAccount(acc);
			// 发送玩家状态
			ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
			Transmitter.getInstance().write(serverService.getGatewayNode(3000), GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
	}



	/**
	 * 队长点击开始战斗
	 * @param message
	 */
	public void startTeamBattle(GBStartTeamBattleREQ message) {
		TeamInfo teamInfo = message.getTeamInfo();
		int missionId = teamInfo.getMissionId();
		long id = teamInfo.getId();
		String roomId = "team_" + String.valueOf(missionId)+"_" + String.valueOf(id);
		BattleHelper battleHelper = battleHelpers.get(roomId);
		if(battleHelper == null){
			battleHelper = new BattleHelper(missionId);
			battleHelpers.put(roomId, battleHelper);
		}else {
			return;
		}
		
		BattleMap battleMap = battleHelper.battleMap;
		List<TeamPlayerInfo> teamPlayerInfos = teamInfo.getTeamPlayerInfosList();
		
		for(int i = 0; i<teamPlayerInfos.size(); i++){
			TeamPlayerInfo teamPlayerInfo = teamPlayerInfos.get(i);
			PlayerInfo playerInfo = teamPlayerInfo.getPlayerInfo();
			String account = playerInfo.getAccount();
			if(i == 0){
				battleMap.roomOwner = account;
			}
			int bornx = battleMap.playerBornPosList.get(i).NodeX;
			int borny = battleMap.playerBornPosList.get(i).NodeY;
			accountTeams.put(account, roomId);
			PlayerFightUnit playerUnit = new PlayerFightUnit(bornx, borny,playerInfo);
			battleMap.addPlayer(account, playerUnit);
		}
		battleMap.initAfterMemberJoined();
		
		BGStartTeamBattleRES.Builder res = BGStartTeamBattleRES.newBuilder();
		res.setResult(ProtocolsConfig.START_TEAM_BATTLE_SUCCESS);
		res.setAccount(message.getAccount());
		res.setTeamInfo(message.getTeamInfo());
		
		ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
		Transmitter.getInstance().write(serverService.getGameNode(), GlobalConstants.DEFAULT_CALLBACK, res.build());
	}
	
	public void startSingleBattle(GBStartSingleBattleREQ message) {
		PlayerInfo playerInfo = message.getSingleBattleInfo().getPlayerInfo();
		String account = playerInfo.getAccount();
		int missionId = message.getSingleBattleInfo().getMissionId();
		String roomId = "single_" + missionId +"_" + account;
		BattleHelper battleHelper = battleHelpers.get(roomId);
		if (battleHelper == null) {
			battleHelper = new BattleHelper(missionId);
			battleHelpers.put(roomId, battleHelper);
		} else {
			// TODO 临时处理, 强退后重新进入这个关卡，就给他开一个新的room
			battleHelper = new BattleHelper(missionId);
			battleHelpers.put(roomId, battleHelper);
		}
		BattleMap battleMap = battleHelper.battleMap;
		int bornX = battleMap.playerBornPosList.get(0).NodeX;
		int bornY = battleMap.playerBornPosList.get(0).NodeY;
		accountTeams.put(account, roomId);
		PlayerFightUnit playerUnit = new PlayerFightUnit(bornX, bornY, playerInfo);
		battleMap.addPlayer(account, playerUnit);
		battleMap.initAfterMemberJoined();
		
		BGStartSingleBattleRES.Builder res = BGStartSingleBattleRES.newBuilder();
		res.setResult(ProtocolsConfig.START_SINGLE_BATTLE_SUCCESS);
		res.setAccount(account);
		ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
		Transmitter.getInstance().write(serverService.getGameNode(),  GlobalConstants.DEFAULT_CALLBACK, res.build());
	}

	public void tmpDestoryRoom(GBTmpDestoryRoomREQ message) {
		int missionId = message.getMissionId();
		long teamId = message.getTeamId();
		String roomId = "team_" + String.valueOf(missionId)+"_" + String.valueOf(teamId);
		this.destoryRoom(roomId);
	}
}
